#include <iostream>
#include <string>
// 包含SpireMS SDK头文件
#include <sms_core.h>


const char* about = "32 Nodes Stress Test with Share Memory (RECV)";
const char* keys  =
    "{@node_id   |<none> | Node ID }";

class ShareMemReceiverTest
{
public:
    ShareMemReceiverTest(int id) : _sub(
        "/share_mem/image_" + std::to_string(id), 
        "memory_msgs::RawImage", 
        std::bind(&ShareMemReceiverTest::callback, this, std::placeholders::_1)
    )
    {
        img_cnt = 0;
        dt_tot = 0.0;
        print_dt = true;
    }
    void callback(nlohmann::json msg)
    {
        // std::cout << "  " << sms::get_time_sec() - msg["timestamp"].get<double>() << std::endl;
        cv::Mat cvimg = sms::sms2cvimg(msg);
        
        // std::cout << sms::get_time_sec() - msg["timestamp"].get<double>() << std::endl;
        dt_tot += sms::get_time_sec() - msg["timestamp"].get<double>();
        img_cnt += 1;
        if (print_dt && img_cnt > 600)
        {
            std::cout << dt_tot / img_cnt << std::endl;
            print_dt = false;
        }
        
        cv::imshow("img", cvimg);
        cv::waitKey(3);
    }
    void join()
    {
        this->_sub.join();
    }

private:
    sms::Subscriber _sub;
    int img_cnt;
    double dt_tot;
    bool print_dt;
};


int main(int argc, char *argv[])
{
    cv::CommandLineParser parser(argc, argv, keys);
    parser.about(about);

    if(argc < 1) {
        parser.printMessage();
        return 0;
    }

    std::cout << "node_id: " << parser.get<int>(0) << std::endl;
    
    sms::mem_init();

    ShareMemReceiverTest tt(parser.get<int>(0));
    tt.join();
    return 0;
}

